﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AddIn.EA.Framework.Common;

namespace AddIn.EA.Framework
{
    /// <summary>
    /// Represents a list of connectors
    /// </summary>
    public class ConnectorList : BaseList<Connector>
    {
        #region Constructors
        /// <summary>
        /// Get an instance of an connector list.
        /// </summary>
        /// <param name="reference">The reference of EA Object Model element collection</param>
        /// <param name="parent"></param>
        public ConnectorList(EA_Application.Collection reference, IElement parent)
            : base(reference, parent) { }
        #endregion

        #region Public Methods
        /// <summary>
        /// Add new connector in the connector list
        /// </summary>
        /// <param name="name">The name of element</param>
        /// <param name="type">The type of element</param>
        /// <returns>An element instance</returns>
        public Connector AddNew(string name, Connector.ConnectorType type)
        {
            return base.AddNew(name, type.ToString());
        }
        /// <summary>
        /// Add new connector in the connector list
        /// The default type applyed is "Generalization". 
        /// If you want to define another type of Connector, use the overload to provide the type.
        /// </summary>
        /// <param name="name">The name of element</param>
        /// <returns>An element instance</returns>
        public override Connector AddNew(string name)
        {
            return base.AddNew(name, Connector.ConnectorType.Generalization.ToString());
        }

        /// <summary>
        /// This method don´t shall be used.
        /// </summary>
        public override Connector AddNew(string name, string type)
        {
            throw new InvalidOperationException("This method cannot be used in this context. Try to use the method AddNew(string, ElementType)!");
        }
        #endregion
    }

    /// <summary>
    /// Represents a connector which make a reference link between two objects.
    /// </summary>
    public class Connector : BaseElement<EA_Application.Connector>
    {
        #region Enum
        public enum ConnectorType
        {
            Aggregation,
            Assembly,
            Association,
            Collaboration,
            CommunicationPath,
            Connector,
            ControlFlow,
            Delegate,
            Dependency,
            Deployment,
            ERLink,
            Generalization,
            InformationFlow,
            Instantiation,
            InterruptFlow,
            Manifest,
            Nesting,
            NoteLink,
            ObjectFlow,
            Package,
            Realization,
            Sequence,
            StateFlow,
            UseCase
        }
        public enum ConnectorDirection
        {
            Unspecified,
            BiDirectional,
            SourceDestination,
            DestinationSource
        }
        #endregion

        #region Properties
        public int ClientID
        {
            get { return base.Reference.ClientID; }
            set { base.Reference.ClientID = value; }
        }
        public ConnectorDirection Direction
        {
            get { return GetConnectorDirection(base.Reference.Direction); }
            set { base.Reference.Direction = GetConnectorDirectionDescription(value); }
        }
        public int SupplierID
        {
            get { return base.Reference.SupplierID; }
            set { base.Reference.SupplierID = value; }
        }
        public ConnectorType Type
        {
            get { return (ConnectorType)Enum.Parse(typeof(ConnectorType), base.Reference.Type); }
            set { base.Reference.Type = value.ToString(); }
        }
        public Boolean VirtualInheritance
        {
            get { return base.Reference.VirtualInheritance.CompareTo("1") == 0 ? true : false; }
            set { base.Reference.VirtualInheritance = value ? "1" : "0"; }
        }
        #endregion

        #region BaseElement Members
        /// <summary>
        /// The element id
        /// </summary>
        public override int ID
        {
            get { return this.Reference.ConnectorID; }
        }
        /// <summary>
        /// The element name
        /// </summary>
        public override string Name
        {
            get { return this.Reference.Name; }
            set { this.Reference.Name = value; }
        }
        #endregion

        #region Constructors
        /// <summary>
        /// Get an instance of Element
        /// </summary>
        /// <param name="reference">The reference of EA Object Model element</param>
        /// <param name="parent">The parent element</param>
        public Connector(EA_Application.Connector reference, IElement parent)
            : base(reference, parent)
        {
        }
        #endregion

        #region Private Methods
        private ConnectorDirection GetConnectorDirection(String direction)
        {
            switch (direction)
            {
                case "Unspecified":
                    return ConnectorDirection.Unspecified;
                case "Bi-Directional":
                    return ConnectorDirection.BiDirectional;
                case "Source -> Destination":
                    return ConnectorDirection.SourceDestination;
                case "Destination -> Source":
                    return ConnectorDirection.DestinationSource;
                default:
                    return ConnectorDirection.Unspecified;
            }
        }
        private string GetConnectorDirectionDescription(ConnectorDirection direction)
        {
            switch (direction)
            {
                case ConnectorDirection.Unspecified:
                    return "Unspecified";
                case ConnectorDirection.BiDirectional:
                    return "Bi-Directional";
                case ConnectorDirection.SourceDestination:
                    return "Source -> Destination";
                case ConnectorDirection.DestinationSource:
                    return "Destination -> Source";
                default:
                    return "Unspecified";
            }
        }
        #endregion
    }
}
